import os
import tkinter as tk
from tkinter import ttk, messagebox
import customtkinter
import threading
from database import Database
from ssh_client import DeployTool
from ui_forms import (
    LogWindow, ServerConfigWindow, DbConfigWindow,
    ProjectConfigWindow, DeployProgressWindow
)
from logger_config import logger

# 设置中文字体支持
customtkinter.set_appearance_mode("light")  # 可选模式: "system", "light", "dark"
customtkinter.set_default_color_theme("blue")  # 可选主题: "blue", "green", "dark-blue"


class DeployApp(customtkinter.CTk):
    def __init__(self):
        super().__init__()
        self.title("一键部署工具")
        self.geometry("1200x600")

        # 初始化数据库
        self.db = Database()

        # 初始化部署工具
        self.deploy_tool = DeployTool(self.db)

        # 日志窗口
        self.log_window = None

        self.init_ui()

    def init_ui(self):
        # 创建主框架
        main_frame = customtkinter.CTkFrame(self)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 左侧服务器列表
        left_frame = customtkinter.CTkFrame(main_frame, width=250)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False, padx=(0, 10), pady=5)

        # 服务器列表标题
        server_title_frame = customtkinter.CTkFrame(left_frame)
        server_title_frame.pack(fill=tk.X, padx=5, pady=5)

        customtkinter.CTkLabel(server_title_frame, text="服务器列表", font=("Arial", 14, "bold")).pack(side=tk.LEFT)

        server_btn_frame = customtkinter.CTkFrame(server_title_frame)
        server_btn_frame.pack(side=tk.RIGHT)

        self.add_server_btn = customtkinter.CTkButton(server_btn_frame, text="+", width=30, command=self.add_server)
        self.add_server_btn.pack(side=tk.LEFT, padx=2)

        self.edit_server_btn = customtkinter.CTkButton(server_btn_frame, text="✎", width=30, command=self.edit_server,
                                                       state=tk.DISABLED)
        self.edit_server_btn.pack(side=tk.LEFT, padx=2)

        self.delete_server_btn = customtkinter.CTkButton(server_btn_frame, text="✕", width=30,
                                                         command=self.delete_server, state=tk.DISABLED)
        self.delete_server_btn.pack(side=tk.LEFT, padx=2)

        # 服务器列表
        self.server_listbox = tk.Listbox(left_frame, selectmode=tk.SINGLE, width=30, height=20)
        self.server_listbox.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        self.server_listbox.bind('<<ListboxSelect>>', self.on_server_select)

        # 添加滚动条
        server_scrollbar = customtkinter.CTkScrollbar(left_frame, command=self.server_listbox.yview)
        server_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.server_listbox.configure(yscrollcommand=server_scrollbar.set)

        # 右侧信息区域 - 使用笔记本控件切换项目和数据库配置
        right_frame = customtkinter.CTkFrame(main_frame)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 创建笔记本控件
        self.notebook = ttk.Notebook(right_frame)
        self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 项目标签页
        self.project_frame = customtkinter.CTkFrame(self.notebook)
        self.notebook.add(self.project_frame, text="项目部署")

        # 数据库配置标签页
        self.db_config_frame = customtkinter.CTkFrame(self.notebook)
        self.notebook.add(self.db_config_frame, text="数据库配置")

        # 初始化项目标签页
        self.init_project_tab()

        # 初始化数据库配置标签页
        self.init_db_config_tab()

        # 底部状态栏
        status_frame = customtkinter.CTkFrame(self, height=30)
        status_frame.pack(fill=tk.X, side=tk.BOTTOM, padx=10, pady=5)

        self.log_btn = customtkinter.CTkButton(status_frame, text="查看日志", command=self.show_logs)
        self.log_btn.pack(side=tk.RIGHT, padx=10, pady=5)

        # 刷新服务器列表
        self.refresh_server_list()

    def init_project_tab(self):
        """初始化项目标签页"""
        # 项目列表标题
        project_title_frame = customtkinter.CTkFrame(self.project_frame)
        project_title_frame.pack(fill=tk.X, padx=5, pady=5)

        self.project_title_label = customtkinter.CTkLabel(self.project_frame, text="请选择服务器",
                                                          font=("Arial", 14, "bold"))
        self.project_title_label.pack(in_=project_title_frame, side=tk.LEFT)

        project_btn_frame = customtkinter.CTkFrame(self.project_frame)
        project_btn_frame.pack(in_=project_title_frame, side=tk.RIGHT)

        self.add_project_btn = customtkinter.CTkButton(self.project_frame, text="添加项目", command=self.add_project,
                                                       state=tk.DISABLED)
        self.add_project_btn.pack(in_=project_btn_frame, side=tk.LEFT, padx=2)

        self.edit_project_btn = customtkinter.CTkButton(self.project_frame, text="编辑项目", command=self.edit_project,
                                                        state=tk.DISABLED)
        self.edit_project_btn.pack(in_=project_btn_frame, side=tk.LEFT, padx=2)

        self.delete_project_btn = customtkinter.CTkButton(self.project_frame, text="删除项目",
                                                          command=self.delete_project, state=tk.DISABLED)
        self.delete_project_btn.pack(in_=project_btn_frame, side=tk.LEFT, padx=2)

        self.deploy_project_btn = customtkinter.CTkButton(self.project_frame, text="部署", command=self.deploy_project,
                                                          state=tk.DISABLED)
        self.deploy_project_btn.pack(in_=project_btn_frame, side=tk.LEFT, padx=2)

        # 项目列表
        columns = ("id", "名称", "类型", "本地路径", "远程路径", "操作")
        self.project_tree = ttk.Treeview(self.project_frame, columns=columns, show="headings")

        # 设置列宽和标题
        self.project_tree.column("id", width=50, anchor=tk.CENTER)
        self.project_tree.column("名称", width=100, anchor=tk.W)
        self.project_tree.column("类型", width=80, anchor=tk.CENTER)
        self.project_tree.column("本地路径", width=200, anchor=tk.W)
        self.project_tree.column("远程路径", width=200, anchor=tk.W)
        self.project_tree.column("操作", width=100, anchor=tk.CENTER)

        self.project_tree.heading("id", text="ID")
        self.project_tree.heading("名称", text="名称")
        self.project_tree.heading("类型", text="类型")
        self.project_tree.heading("本地路径", text="本地路径")
        self.project_tree.heading("远程路径", text="远程路径")
        self.project_tree.heading("操作", text="操作")

        self.project_tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        self.project_tree.bind('<<TreeviewSelect>>', self.on_project_select)
        self.project_tree.bind('<Button-1>', self.on_project_click)

        # 添加滚动条
        project_scrollbar_y = customtkinter.CTkScrollbar(self.project_frame, command=self.project_tree.yview)
        project_scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
        self.project_tree.configure(yscrollcommand=project_scrollbar_y.set)

        project_scrollbar_x = customtkinter.CTkScrollbar(self.project_frame, command=self.project_tree.xview,
                                                         orientation=tk.HORIZONTAL)
        project_scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.project_tree.configure(xscrollcommand=project_scrollbar_x.set)

    def init_db_config_tab(self):
        """初始化数据库配置标签页"""
        # 数据库配置标题
        db_title_frame = customtkinter.CTkFrame(self.db_config_frame)
        db_title_frame.pack(fill=tk.X, padx=5, pady=5)

        self.db_title_label = customtkinter.CTkLabel(self.db_config_frame, text="请选择服务器",
                                                     font=("Arial", 14, "bold"))
        self.db_title_label.pack(in_=db_title_frame, side=tk.LEFT)

        db_btn_frame = customtkinter.CTkFrame(self.db_config_frame)
        db_btn_frame.pack(in_=db_title_frame, side=tk.RIGHT)

        self.add_db_config_btn = customtkinter.CTkButton(self.db_config_frame, text="添加配置",
                                                         command=self.add_db_config, state=tk.DISABLED)
        self.add_db_config_btn.pack(in_=db_btn_frame, side=tk.LEFT, padx=2)

        self.edit_db_config_btn = customtkinter.CTkButton(self.db_config_frame, text="编辑配置",
                                                          command=self.edit_db_config, state=tk.DISABLED)
        self.edit_db_config_btn.pack(in_=db_btn_frame, side=tk.LEFT, padx=2)

        self.delete_db_config_btn = customtkinter.CTkButton(self.db_config_frame, text="删除配置",
                                                            command=self.delete_db_config, state=tk.DISABLED)
        self.delete_db_config_btn.pack(in_=db_btn_frame, side=tk.LEFT, padx=2)

        # 数据库配置列表
        columns = ("id", "名称", "类型", "主机", "端口", "数据库", "用户名")
        self.db_config_tree = ttk.Treeview(self.db_config_frame, columns=columns, show="headings")

        # 设置列宽和标题
        self.db_config_tree.column("id", width=50, anchor=tk.CENTER)
        self.db_config_tree.column("名称", width=100, anchor=tk.W)
        self.db_config_tree.column("类型", width=100, anchor=tk.CENTER)
        self.db_config_tree.column("主机", width=150, anchor=tk.W)
        self.db_config_tree.column("端口", width=80, anchor=tk.CENTER)
        self.db_config_tree.column("数据库", width=120, anchor=tk.W)
        self.db_config_tree.column("用户名", width=100, anchor=tk.W)

        self.db_config_tree.heading("id", text="ID")
        self.db_config_tree.heading("名称", text="名称")
        self.db_config_tree.heading("类型", text="类型")
        self.db_config_tree.heading("主机", text="主机")
        self.db_config_tree.heading("端口", text="端口")
        self.db_config_tree.heading("数据库", text="数据库")
        self.db_config_tree.heading("用户名", text="用户名")

        self.db_config_tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        self.db_config_tree.bind('<<TreeviewSelect>>', self.on_db_config_select)

        # 添加滚动条
        db_scrollbar_y = customtkinter.CTkScrollbar(self.db_config_frame, command=self.db_config_tree.yview)
        db_scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
        self.db_config_tree.configure(yscrollcommand=db_scrollbar_y.set)

        db_scrollbar_x = customtkinter.CTkScrollbar(self.db_config_frame, command=self.db_config_tree.xview,
                                                    orientation=tk.HORIZONTAL)
        db_scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.db_config_tree.configure(xscrollcommand=db_scrollbar_x.set)

    def refresh_server_list(self):
        """刷新服务器列表"""
        self.server_listbox.delete(0, tk.END)
        self.servers = self.db.get_server_list()  # (id, name, ip, port, username, desc)

        for server in self.servers:
            self.server_listbox.insert(tk.END, f"{server[1]} ({server[2]})")

        # 重置按钮状态
        self.edit_server_btn.configure(state=tk.DISABLED)
        self.delete_server_btn.configure(state=tk.DISABLED)
        self.add_project_btn.configure(state=tk.DISABLED)
        self.add_db_config_btn.configure(state=tk.DISABLED)
        self.clear_project_list()
        self.clear_db_config_list()

    def clear_project_list(self):
        """清空项目列表"""
        for item in self.project_tree.get_children():
            self.project_tree.delete(item)

        self.edit_project_btn.configure(state=tk.DISABLED)
        self.delete_project_btn.configure(state=tk.DISABLED)
        self.deploy_project_btn.configure(state=tk.DISABLED)

    def refresh_project_list(self, server_id):
        """刷新指定服务器的项目列表"""
        self.clear_project_list()

        projects = self.db.get_projects_by_server(
            server_id)  # (id, name, type, local_path, remote_path, start_command, stop_command, desc)

        for project in projects:
            short_local_path = os.path.basename(project[3]) if project[3] else ""
            self.project_tree.insert("", tk.END, values=(
                project[0],
                project[1],
                "Vue" if project[2] == "vue" else "JAR",
                short_local_path,
                project[4],
                "部署"
            ))

    def clear_db_config_list(self):
        """清空数据库配置列表"""
        for item in self.db_config_tree.get_children():
            self.db_config_tree.delete(item)

        self.edit_db_config_btn.configure(state=tk.DISABLED)
        self.delete_db_config_btn.configure(state=tk.DISABLED)

    def refresh_db_config_list(self, server_id):
        """刷新指定服务器的数据库配置列表"""
        self.clear_db_config_list()

        configs = self.db.get_db_configs_by_server(
            server_id)  # (id, name, type, host, port, database, username, password, desc)

        for config in configs:
            self.db_config_tree.insert("", tk.END, values=(
                config[0],
                config[1],
                config[2],
                config[3],
                config[4],
                config[5],
                config[6]
            ))

    def on_server_select(self, event):
        """服务器选择事件"""
        selection = self.server_listbox.curselection()
        if not selection:
            self.edit_server_btn.configure(state=tk.DISABLED)
            self.delete_server_btn.configure(state=tk.DISABLED)
            self.add_project_btn.configure(state=tk.DISABLED)
            self.add_db_config_btn.configure(state=tk.DISABLED)
            self.clear_project_list()
            self.clear_db_config_list()
            self.project_title_label.configure(text="请选择服务器")
            self.db_title_label.configure(text="请选择服务器")
            return

        index = selection[0]
        if index < 0 or index >= len(self.servers):
            return

        server = self.servers[index]
        self.current_server_id = server[0]

        # 更新按钮状态
        self.edit_server_btn.configure(state=tk.NORMAL)
        self.delete_server_btn.configure(state=tk.NORMAL)
        self.add_project_btn.configure(state=tk.NORMAL)
        self.add_db_config_btn.configure(state=tk.NORMAL)

        # 更新标题
        self.project_title_label.configure(text=f"项目列表 - {server[1]} ({server[2]})")
        self.db_title_label.configure(text=f"数据库配置 - {server[1]} ({server[2]})")

        # 刷新项目列表和数据库配置列表
        self.refresh_project_list(server[0])
        self.refresh_db_config_list(server[0])

    def on_project_select(self, event):
        """项目选择事件"""
        selection = self.project_tree.selection()
        if not selection:
            self.edit_project_btn.configure(state=tk.DISABLED)
            self.delete_project_btn.configure(state=tk.DISABLED)
            self.deploy_project_btn.configure(state=tk.DISABLED)
            return

        item = selection[0]
        project_id = self.project_tree.item(item, "values")[0]
        self.current_project_id = project_id

        # 更新按钮状态
        self.edit_project_btn.configure(state=tk.NORMAL)
        self.delete_project_btn.configure(state=tk.NORMAL)
        self.deploy_project_btn.configure(state=tk.NORMAL)

    def on_project_click(self, event):
        """项目点击事件，用于处理"部署"按钮点击"""
        region = self.project_tree.identify_region(event.x, event.y)
        item = self.project_tree.identify_row(event.y)
        column = int(self.project_tree.identify_column(event.x).replace('#', ''))

        if region == "cell" and item and column == 6:  # 第六列是操作列
            project_id = self.project_tree.item(item, "values")[0]
            project_name = self.project_tree.item(item, "values")[1]
            self.current_project_id = project_id
            self.start_deploy(project_id, project_name)

    def on_db_config_select(self, event):
        """数据库配置选择事件"""
        selection = self.db_config_tree.selection()
        if not selection:
            self.edit_db_config_btn.configure(state=tk.DISABLED)
            self.delete_db_config_btn.configure(state=tk.DISABLED)
            return

        item = selection[0]
        config_id = self.db_config_tree.item(item, "values")[0]
        self.current_config_id = config_id

        # 更新按钮状态
        self.edit_db_config_btn.configure(state=tk.NORMAL)
        self.delete_db_config_btn.configure(state=tk.NORMAL)

    def add_server(self):
        """添加服务器"""
        ServerConfigWindow(self, self.db)

    def edit_server(self):
        """编辑服务器"""
        selection = self.server_listbox.curselection()
        if not selection:
            return

        index = selection[0]
        server_id = self.servers[index][0]
        ServerConfigWindow(self, self.db, server_id)

    def delete_server(self):
        """删除服务器"""
        selection = self.server_listbox.curselection()
        if not selection:
            return

        index = selection[0]
        server_id = self.servers[index][0]
        server_name = self.servers[index][1]

        if messagebox.askyesno("确认", f"确定要删除服务器 '{server_name}' 吗？\n相关的项目和数据库配置也将被删除。"):
            try:
                self.db.delete_server(server_id)
                messagebox.showinfo("成功", "服务器删除成功")
                logger.info(f"删除服务器: {server_name}")
                self.refresh_server_list()
            except Exception as e:
                messagebox.showerror("错误", f"删除失败: {str(e)}")
                logger.error(f"删除服务器失败: {str(e)}")

    def add_project(self):
        """添加项目"""
        if not hasattr(self, 'current_server_id'):
            messagebox.showwarning("提示", "请先选择一个服务器")
            return

        ProjectConfigWindow(self, self.db, self.current_server_id)

    def edit_project(self):
        """编辑项目"""
        if not hasattr(self, 'current_project_id'):
            return

        ProjectConfigWindow(self, self.db, self.current_server_id, self.current_project_id)

    def delete_project(self):
        """删除项目"""
        if not hasattr(self, 'current_project_id'):
            return

        # 获取项目名称
        selection = self.project_tree.selection()
        if selection:
            item = selection[0]
            project_name = self.project_tree.item(item, "values")[1]

            if messagebox.askyesno("确认", f"确定要删除项目 '{project_name}' 吗？"):
                try:
                    self.db.delete_project(self.current_project_id)
                    messagebox.showinfo("成功", "项目删除成功")
                    logger.info(f"删除项目: {project_name}")
                    self.refresh_project_list(self.current_server_id)
                except Exception as e:
                    messagebox.showerror("错误", f"删除失败: {str(e)}")
                    logger.error(f"删除项目失败: {str(e)}")

    def add_db_config(self):
        """添加数据库配置"""
        if not hasattr(self, 'current_server_id'):
            messagebox.showwarning("提示", "请先选择一个服务器")
            return

        DbConfigWindow(self, self.db, self.current_server_id)

    def edit_db_config(self):
        """编辑数据库配置"""
        if not hasattr(self, 'current_config_id'):
            return

        DbConfigWindow(self, self.db, self.current_server_id, self.current_config_id)

    def delete_db_config(self):
        """删除数据库配置"""
        if not hasattr(self, 'current_config_id'):
            return

        # 获取配置名称
        selection = self.db_config_tree.selection()
        if selection:
            item = selection[0]
            config_name = self.db_config_tree.item(item, "values")[1]

            if messagebox.askyesno("确认", f"确定要删除数据库配置 '{config_name}' 吗？"):
                try:
                    self.db.delete_db_config(self.current_config_id)
                    messagebox.showinfo("成功", "数据库配置删除成功")
                    logger.info(f"删除数据库配置: {config_name}")
                    self.refresh_db_config_list(self.current_server_id)
                except Exception as e:
                    messagebox.showerror("错误", f"删除失败: {str(e)}")
                    logger.error(f"删除数据库配置失败: {str(e)}")

    def show_logs(self):
        """显示日志窗口"""
        if self.log_window is None or not self.log_window.winfo_exists():
            self.log_window = LogWindow(self)
        else:
            self.log_window.focus()
            self.log_window.load_logs()  # 刷新日志内容

    def deploy_project(self):
        """部署项目"""
        if not hasattr(self, 'current_project_id'):
            return

        # 获取项目名称
        selection = self.project_tree.selection()
        if not selection:
            return

        item = selection[0]
        project_name = self.project_tree.item(item, "values")[1]

        self.start_deploy(self.current_project_id, project_name)

    def start_deploy(self, project_id, project_name):
        """开始部署项目"""
        # 创建进度窗口
        self.progress_window = DeployProgressWindow(self, project_name)

        # 在新线程中执行部署，避免界面卡顿
        def deploy_thread():
            success, msg = self.deploy_tool.deploy_project(
                project_id,
                lambda value, msg: self.progress_window.update_progress(value, msg)
            )

            # 更新进度窗口结果
            self.progress_window.set_result(success, msg)

            # 如果部署成功，记录日志
            if success:
                logger.info(f"项目部署成功: {project_name}")
            else:
                logger.error(f"项目部署失败: {project_name}, {msg}")

        # 启动部署线程
        threading.Thread(target=deploy_thread, daemon=True).start()


if __name__ == "__main__":
    # 确保中文显示正常
    app = DeployApp()
    app.mainloop()
